from flask import request, jsonify, Blueprint
from app import db
from db.models import User, TestRecord
from datetime import datetime
import numpy as np
import pandas as pd
import torch
import joblib
from model.MLP import CardioMLP
from sqlalchemy.exc import SQLAlchemyError
from flask_login import login_user, logout_user, login_required, current_user
from sklearn.preprocessing import StandardScaler
from sqlalchemy import or_

# model_path = 'model/cardio_model.pth'
# scaler_path = 'model/scaler.save'
# model = torch.load(model_path)
# scaler = joblib.load("scaler.save")
model_state_dict = torch.load('model/cardio_model.pth')
model = CardioMLP()
model.load_state_dict(model_state_dict)
model.eval()
scaler_path = 'model/scaler.save'
scaler = joblib.load(scaler_path)

api = Blueprint('api', __name__)


@api.route('/login', methods=['GET', 'POST'])
def login():
    data = request.json
    print("Received data:", data)
    username_or_email = data.get('username_or_email')
    password = data.get('password')
    print("Username:", username_or_email, "Password:", password)

    user = User.query.filter(or_(User.username == username_or_email, User.email == username_or_email)).first()

    if user is None:
        print('user not found')
        return jsonify({"message": "没有该用户", "status": "error"}), 404
    else:
        if user.password == password:
            login_user(user)
            return jsonify({"message": "登录成功", "status": "success", "username": user.username}), 200
        else:
            return jsonify({"message": "密码错误", "status": "error"}), 401


@api.route('/register', methods=['POST'])
def register():
    data = request.json
    username = data.get('username')
    password = data.get('password')
    email = data.get('email')

    existing_user = User.query.filter((User.username == username) | (User.email == email)).first()
    if existing_user:
        return jsonify({"message": "该用户名或邮箱已存在", "status": "error"}), 400
    new_user = User(id=username, username=username, password=password, email=email)
    db.session.add(new_user)
    db.session.commit()

    return jsonify({"message": "注册成功", "status": "success"}), 200


@api.route('/logout', methods=['GET', 'POST'])
@login_required
def logout():
    logout_user()
    return jsonify({"message": "已登出"}), 200


@api.route('/predict', methods=['POST'])
@login_required
def submit_health_data():
    print("开始预测")
    data = request.json
    username = current_user.username
    test_id = datetime.now().strftime("%Y%m%d%H%M%S") + username
    print("数据\n", data)
    try:
        height_m = data['height'] / 100
        bmi = data['weight'] / (height_m ** 2)
        feature_names = ['age', 'gender', 'BMI', 'ap_hi', 'ap_lo', 'cholesterol', 'gluc', 'smoke', 'alco', 'active']

        model_input = pd.DataFrame(np.array([[
            data['age'],
            data['gender'],
            bmi,
            data['ap_hi'],
            data['ap_lo'],
            data['cholesterol'],
            data['gluc'],
            data['smoke'],
            data['alco'],
            data['active']
        ]]), columns=feature_names)

        model_input_scaled = scaler.transform(model_input)
        input_tensor = torch.tensor(model_input_scaled, dtype=torch.float)
        with torch.no_grad():
            output = model(input_tensor)
            probabilities = torch.softmax(output, dim=1)
            prob_0, prob_1 = probabilities.squeeze().tolist()

        advice = {}
        if data['ap_hi'] > 120:
            advice['ap_hi'] = "您的收缩压偏高，建议您定期测量血压，注意低盐饮食。"
        if data['ap_hi'] < 90:
            advice['ap_hi'] = "您的收缩压偏低，建议多吃富含维生素和矿物质的食物，并咨询医生。"

        if data['ap_lo'] > 80:
            advice['ap_lo'] = "您的舒张压偏高，建议进行体力活动，并避免高脂肪饮食。"
        if data['ap_lo'] < 60:
            advice['ap_lo'] = "您的舒张压偏低，建议保持适当的水分摄取，如果有头晕症状，请及时就医。"

        if float(data['cholesterol']) == 2:
            advice['cholesterol'] = "您的胆固醇水平偏高，建议增加膳食纤维的摄入，减少油腻食物。"
        if float(data['cholesterol']) == 3:
            advice['cholesterol'] = "您的胆固醇水平远高于正常，建议严格控制饮食中的饱和脂肪和胆固醇的摄入量，定期进行身体检查，并咨询医生是否需要药物治疗。"

        if float(data['gluc']) == 2:
            advice['gluc'] = "您的葡萄糖水平偏高，建议少吃甜食，多做运动。"
        if float(data['gluc']) == 3:
            advice['gluc'] = "您的葡萄糖水平远高于正常，这可能是糖尿病的迹象。建议立即咨询医生，进行血糖监控和可能的药物治疗，同时积极调整饮食习惯和增加体育活动。"

        if data['smoke'] == 1:
            advice['smoke'] = "建议不要吸烟，吸烟会增加心血管疾病的风险。"
        if data['alco'] == 1:
            advice['alco'] = "建议减少饮酒，过量饮酒会损害您的健康。"

        result = f"患病概率为 {prob_1:.2%}, 不患病概率为 {prob_0:.2%}"

        print('执行到保存')
        new_record = TestRecord(
            test_id=test_id,
            username=username,
            date=datetime.now(),
            result=result,
            age=data['age'],
            gender=data['gender'],
            bmi=bmi,
            ap_hi=data['ap_hi'],
            ap_lo=data['ap_lo'],
            cholesterol=data['cholesterol'],
            gluc=data['gluc'],
            smoke=data['smoke'],
            alco=data['alco'],
            active=data['active']
        )
        db.session.add(new_record)
        db.session.commit()

        print("show result", result)
        print("show advice", advice)

        return jsonify({"message": "Health data submitted successfully", "result": result, "advice": advice}), 200

    except SQLAlchemyError as e:
        db.session.rollback()
        print('Database error: {}'.format(e))
        return jsonify({"message": "Failed to save data to database", "error": str(e)}), 500

    except Exception as e:
        print('Prediction error: {}'.format(e))
        return jsonify({"message": "Error during prediction process", "error": str(e)}), 500


@api.route('/history', methods=['GET'])
@login_required
def get_history():
    username = request.args.get('username')
    page = request.args.get('page', 1, type=int)
    per_page = request.args.get('per_page', 10, type=int)

    print('username', username)

    if not username:
        return jsonify({"message": "用户名不能为空", "status": "error"}), 400

    user = User.query.filter_by(username=username).first()

    if not user:
        return jsonify({"message": "没有该用户的预测数据", "status": "error"}), 404

    pagination = TestRecord.query.filter_by(username=username).paginate(page=page, per_page=per_page, error_out=False)

    records = pagination.items
    if not records:
        return jsonify({"message": "没有找到历史记录", "status": "error"}), 404
    history = []
    for record in records:
        test_id_parts = record.test_id[:-len(username)]
        title = f"{test_id_parts[0][:4]}-{test_id_parts[0][4:6]}-{test_id_parts[0][6:8]} {test_id_parts[0][8:10]}:{test_id_parts[0][10:12]}:{test_id_parts[0][12:14]}"
        print('title:', title)
        history.append({
            "title": title,
            "test_id": record.test_id,
            "date": record.date.strftime('%Y-%m-%d %H:%M:%S'),
            "result": record.result,
            "age": record.age,
            "gender": record.gender,
            "bmi": record.bmi,
            "ap_hi": record.ap_hi,
            "ap_lo": record.ap_lo,
            "cholesterol": record.cholesterol,
            "gluc": record.gluc,
            "smoke": record.smoke,
            "alco": record.alco,
            "active": record.active
        })
    print('执行到结束')

    response = {
        'history': history,
        'total': pagination.total,
        'pages': pagination.pages,
        'current_page': pagination.page
    }

    return jsonify(response), 200

